package actions
{
	import actions.interfaces.IActionManager;
	import actions.interfaces.IActionParticipant;
	import actions.interfaces.IAddAction;

	/**
	 * @author michalr
	 */
	public class ActionsManager implements IActionManager,IAddAction
	{
		private static var _instance:IActionManager;
		private static var actionChains:Array;
		private static var standaloneActions:Array;
		private static var action:Action;

		public function ActionsManager()
		{
			actionChains = [];
		}

		public static function  addAction( actionCall:Function, id:String ):IAddAction
		{
			if (_instance == null) _instance = new ActionsManager();
			if (standaloneActions == null) standaloneActions = [];
			action = new Action( actionCall, id );
			return _instance as IAddAction;
		}

		public static function startChainByID( id:String ):void
		{
			if (actionChains[id] == null) throw new Error( 'There is no chain with id : ' + id );
			_instance.runAction( getChainByID( id ).actions[0] );
		}

		public static function runNextActionFromChain( chainID:String ):void
		{
			var arr:Array = getChainByID( chainID ).actions;
			var action:Action;
			trace( 'run next form chain id : ', chainID,arr );
			action = arr[0];
			action.complete = true;
			arr.splice( 0, 1 );
			if(arr.length == 0)
			{
				trace('koniec lancucha');
				return;
			}
			action = arr[0];
			if (action.iap == null) action.complete = true;
			_instance.runAction( action );
			if (action.iap == null) runNextActionFromChain( action.chainId );
		}

		public static function runStandaloneActionByID( id:String ):void
		{
			if (standaloneActions[id] == null) throw new Error( 'There is no action with id : ' + id + ' in standalone collecion' );
			var action:Action = standaloneActions[id];
			if (action.iap == null) action.complete = true;
			_instance.runAction( action );
		}

		public function fin():void
		{
			if (action.chainId == null)
				standaloneActions[action.id] = action;
		}

		public function runAction( actionData:Object ):void
		{
			var action:Action = actionData as Action;
			trace( 'run action', action.id );
			action.action.apply( null, action.params );
		}

		public function chainID( id:String ):IAddAction
		{
			action.chainId = id;
			if (getChainByID( id ) == null) createChaingWithID( id );
			getChainByID( id ).add( action );
			return _instance as IAddAction;
		}

		public function params( ...params ):IAddAction
		{
			action.params = params;
			return _instance  as IAddAction;
		}

		public function iap( iap:IActionParticipant ):IAddAction
		{
			action.iap = iap;
			action.iap.actionCompleteHandler = action.chainId;
			return _instance as IAddAction;
		}

		private static function getChainByID( id:String ):ActionChain
		{
			return actionChains[id];
		}

		private function createChaingWithID( id:String ):void
		{
			actionChains[id] = new ActionChain( id );
		}
	}
}
import actions.interfaces.IActionParticipant;

class ActionChain
{
	private var _actions:Array = [];
	private var id:String;

	public function ActionChain( id:String )
	{
		this.id = id;
	}

	public function add( action:Action ):void
	{
		_actions.push( action );
	}

	public function get actions():Array
	{
		return _actions;
	}
}
class Action
{
	public var action:Function;
	public var id:String;
	public var chainId:String;
	public var params:Array = [];
	public var complete:Boolean;
	public var iap:IActionParticipant;

	public function Action( action:Function, id:String )
	{
		this.action = action;
		this.id = id;
		complete = false;
	}
}
